package com.fjwt.gz.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.ApiRes;
import com.fjwt.gz.core.third.interfaces.IOfficialService;
import com.fjwt.gz.core.utils.SpringBeansUtil;
import com.fjwt.gz.db.base.BaseAgentApp;
import com.fjwt.gz.db.config.dynamic.WxMpProperties;
import com.fjwt.gz.db.entity.OfficialMenuEntity;
import com.fjwt.gz.service.mapper.OfficialMenuMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 公众号菜单表（只有type为click时，才会触发自动回复事件） 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class OfficialMenuService extends ServiceImpl<OfficialMenuMapper, OfficialMenuEntity> {

    @Autowired
    private OfficialMenuMapper officialMenuMapper;

    @Autowired
    private AgentAppService agentAppService;

    @Autowired
    private IOfficialService officialService;

    /**
     * 公众号创建菜单
     * @param appid
     * @param button
     */
    public String saveMenus(String appid, String button,Long userId) {
        if (StringUtils.isEmpty(appid) || StringUtils.isEmpty(button)) {
            throw new BizException("参数缺失");
        }
        String menuId = "";
        WxMpService wxService = setWxService(appid);

        try {
            wxService.switchoverTo(appid).getMenuService().menuDelete();
            LambdaQueryWrapper<OfficialMenuEntity> delete = new LambdaQueryWrapper<>();
            delete.eq(OfficialMenuEntity::getOfficialAppId,appid);
            officialMenuMapper.delete(delete);

            JSONArray array = JSONArray.parseArray(button);
            for(int i=0;i<array.size();i++){
                log.info("公众号一级菜单参数：{}", JSONObject.toJSONString(array.get(i)));
                OfficialMenuEntity entity =  JSONObject.parseObject(JSONObject.toJSONString(array.get(i)),OfficialMenuEntity.class);
                log.info("公众号一级菜单参数转换：{}",JSONObject.toJSONString(entity));
                entity.setCreatedUid(userId);
                entity.setCreatedAt(new Date());
                entity.setOfficialAppId(appid);
                entity.setMenuKey(entity.getKey());
                log.info("公众号一级菜单参数信息：{}",JSONObject.toJSONString(entity));
                officialMenuMapper.insert(entity);
                if(entity.getSubButtons().size()>0){
                    for(int j=0;j<entity.getSubButtons().size();j++){
                        log.info("公众号二级菜单参数信息【处理前】：{}",JSONObject.toJSONString(entity.getSubButtons().get(j)));
                        OfficialMenuEntity dto =  JSONObject.parseObject(JSONObject.toJSONString(entity.getSubButtons().get(j)),OfficialMenuEntity.class);
                        log.info("公众号二级菜单参数转换：{}",JSONObject.toJSONString(dto));
                        dto.setPid(entity.getMenuId());
                        dto.setCreatedUid(userId);
                        dto.setCreatedAt(new Date());
                        dto.setOfficialAppId(appid);
                        dto.setMenuKey(dto.getKey());
                        log.info("公众号二级菜单参数信息：{}",JSONObject.toJSONString(dto));
                        officialMenuMapper.insert(dto);
                    }
                }
            }
            // 组装参数进行封装自定义菜单
            JSONObject json = createMenuParam(button);
            log.info("创建公众号菜单请求参数：{}",JSONObject.toJSONString(json));
//        menuId = wxService.switchoverTo(appid).getMenuService().menuCreate(JSONObject.toJSONString(json));
            menuId = officialService.menuCreate(JSONObject.toJSONString(json), appid, wxService);
            return menuId;
        } catch (WxErrorException e) {
            log.error("创建菜单失败：{}",e.getMessage());
            String message = e.getMessage().substring(5, 10);
            if ("40055".equals(message)) {
                throw new BizException("创建菜单失败: 无效的URL");
            }
            throw new BizException("创建菜单失败");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public WxMpService setWxService(String appid) {
        List<WxMpProperties.MpConfig> configs = new ArrayList<>();
        if (configs == null || configs.size()==0) {
            BaseAgentApp agentApp = agentAppService.getAgentApp(appid);
            WxMpProperties.MpConfig mpConfig = new WxMpProperties.MpConfig();
            mpConfig.setAppId(appid);
            mpConfig.setSecret(agentApp.getAppSecret());
            mpConfig.setToken(agentApp.getToken());
            mpConfig.setAesKey(agentApp.getAesKey());
            configs.add(mpConfig);
        }
        log.info("公众号配置参数信息：{}", JSON.toJSONString(configs));
        WxMpService service = new WxMpServiceImpl();
        service.setMultiConfigStorages(configs
                .stream().map(a -> {
                    WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
                    configStorage.setAppId(a.getAppId());
                    configStorage.setSecret(a.getSecret());
                    configStorage.setToken(a.getToken());
                    configStorage.setAesKey(a.getAesKey());
                    configStorage.setUseStableAccessToken(true);
                    log.info("公众号发送消息时，相关配置信息（包括获取稳定版的token）：{}", JSON.toJSONString(configStorage));
                    return configStorage;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        return service;
    }

    private JSONObject createMenuParam(String button){
        JSONObject json = new JSONObject();
        JSONArray array = JSONArray.parseArray(button);
        JSONArray dataArr = new JSONArray();
        for(int i=0;i<array.size();i++){
            OfficialMenuEntity entity =  JSONObject.parseObject(JSONObject.toJSONString(array.get(i)),OfficialMenuEntity.class);
            if(null != entity.getType()){
                JSONObject jsonObject = menusButtonCereat(entity);
                dataArr.add(jsonObject);
            }else{
                JSONObject data =  new JSONObject();
                data.put("name",entity.getName());
                JSONArray subButtons = new JSONArray();
                if(entity.getSubButtons().size()>0){
                    for(int j=0;j<entity.getSubButtons().size();j++){
                        OfficialMenuEntity dto =  JSONObject.parseObject(JSONObject.toJSONString(entity.getSubButtons().get(j)),OfficialMenuEntity.class);
                        log.info("subbuttonDto参数：{}",JSONObject.toJSONString(dto));
                        JSONObject jsonObject = menusButtonCereat(dto);
                        subButtons.add(jsonObject);
                    }
                }
                data.put("sub_button",subButtons);
                log.info("组装二级菜单参数信息：{}",JSONObject.toJSONString(data));
                dataArr.add(data);
            }
        }
        json.put("button",dataArr);
        log.info("公众号参数组装完成请求参数：{}",JSONObject.toJSONString(json));
        return json;
    }



    /**
     * 根据菜单类型进行封装
     * @param entity
     * @return
     */
    private JSONObject menusButtonCereat(OfficialMenuEntity entity){
        JSONObject json = new JSONObject();
        json.put("name",entity.getName());
        json.put("type",entity.getType());
        if("click".equals(entity.getType())){
            json.put("key",entity.getKey());
        }
        if("view".equals(entity.getType())){
            json.put("url",entity.getUrl());
        }
        if("miniprogram".equals(entity.getType())){
            json.put("appid",entity.getAppid());
            json.put("pagepath",entity.getPagepath());
        }
        json.put("sub_button",new ArrayList<>());
        return json;
    }

    /**
     * 获取公众号菜单
     * @param appid
     * @return
     */
    public JSONObject getMenus(String appid) {
        if (StringUtils.isEmpty(appid)) {
            throw new BizException("请求参数缺失");
        }
        LambdaQueryWrapper<OfficialMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OfficialMenuEntity::getOfficialAppId, appid);
        queryWrapper.eq(OfficialMenuEntity::getIsDeleted, 0);
        List<OfficialMenuEntity> list = baseMapper.selectList(queryWrapper);
        if (0 == list.size()) {
            return new JSONObject();
        }
        JSONObject json = new JSONObject();
        List<OfficialMenuEntity> menus = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            OfficialMenuEntity entity = list.get(i);
            if (null == entity.getPid()) {
                LambdaQueryWrapper<OfficialMenuEntity> query = new LambdaQueryWrapper<>();
                query.eq(OfficialMenuEntity::getOfficialAppId, list.get(i).getOfficialAppId());
                query.eq(OfficialMenuEntity::getPid, entity.getMenuId());
                query.eq(OfficialMenuEntity::getIsDeleted, 0);
                List<OfficialMenuEntity> subbton = baseMapper.selectList(query);
                entity.setKey(entity.getMenuKey());
                if(subbton.size()>0){
                    for(OfficialMenuEntity dto:subbton){
                        dto.setKey(dto.getMenuKey());
                    }
                }
                entity.setSubButtons(subbton);
                menus.add(entity);
            }
        }
        json.put("button", menus);
        return json;
    }

    /**
     * 删除公众号菜单
     * @param menuId
     */
    public void deleteMenus(Long menuId) {
        if (null == menuId) {
            throw new BizException("请求参数缺失");
        }
        boolean flag = this.lambdaUpdate()
                .set(OfficialMenuEntity::getIsDeleted, 1)
                .eq(OfficialMenuEntity::getMenuId, menuId)
                .update();
        if (!flag) {
            throw new BizException("操作失败！");
        }
    }
}
